package info.sean.util.common;


import info.sean.logger.GmfLogger;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;

/**
 * @Description TODO
 * @Author Administrator
 * @Date 2019/3/21 17:18
 */
public class DateUtil {
	private static Logger GMFLOGGER = GmfLogger.getLogger(DateUtil.class);
	public static final String FORMAT="yyyyMMdd";
	public static final String HMS_FORMAT = "HHmmss";
	public static final String FORMAT_YERAR="yyyy";
	public static final String Y_M_D_SPACE_FORMAT="yyyy-MM-dd";
	public static final String Y_M_D_H_M_S_SPACE_FORMAT="yyyy-MM-dd HH:mm:ss";
    public static final String YMDHMSS="yyyyMMddHHmmss";
    public static final String H_M_S_FORMAT="HH:mm:ss";
    public static final String[] PARSE_PATTERNS = {"yyyyMMddHHmmss","yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm:ss","yyyy-MM-dd HH:mm",
			 "yyyy/MM/dd HH:mm","yyyyMMdd HH:mm:ss", "yyyyMMdd", "yyyy-MM-dd", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM", "yyyyMM"};

  /*
	public static final String[] PARSE_PATTERNS = {"yyyyMMdd", "yyyy-MM-dd",
			"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd",
			"yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyyMMdd HH:mm:ss"};
*/

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param now       当前时间
     * @param startTime 开始时间段
     * @param endTime   结束时间段
     * @return
     */
    public static boolean isEffectiveDate(Date now, String startTime, String endTime) throws ParseException {
        return isEffectiveDate(now, startTime, endTime, "HH:mm");
    }

    public static boolean isEffectiveDate(Date now, String startTime, String endTime,String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String nowtTime = sdf.format(now);
        Date nowDate = sdf.parse(nowtTime);
        Date startDate = sdf.parse(startTime);
        Date endDate = sdf.parse(endTime);

        if (nowDate.getTime() == startDate.getTime()
                || nowDate.getTime() == endDate.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowDate);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startDate);

        Calendar end = Calendar.getInstance();
        end.setTime(endDate);

        if(begin.after(end)) {// 起止时间跨天
            if (date.after(begin) || date.before(end)) {
                return true;
            } else {
                return false;
            }
        } else {
            if (date.after(begin) && date.before(end)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 把日期类型格式化成字符串
     * @param date
     * @param format
     * @return
     */
    public static String convert2String(Date date, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
		return formater.format(date);
    }

    /**
     * 把字符串转化为 日期格式
     * @param str
     * @param format
     * @return
     */
    public static Date convert2Date(String str, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            return formater.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 毫秒数转换成时间对象
     * @param dateTimeString String
     * @param pattern StrUtils.DATE_TIME_PATTERN || StrUtils.DATE_PATTERN，如果为空，则为yyyy-MM-dd
     * @return
     */
    public static Date numToDate(String dateTimeString,String pattern) {
        try {
            long milliSecond = Long.parseLong(dateTimeString);
            Date date = new Date();
            date.setTime(milliSecond);
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.parse(sdf.format(date));
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 在指定时间上增加天个数
     * @param beginDate
     * @param day
     * @return Date
     * @author liuxiaoyu
     */
    public static Date addDay(Date beginDate, int day) {
        try {
            if (beginDate == null){
                return null;
            }
            Calendar date = Calendar.getInstance();
            date.setTime(beginDate);
            date.add(Calendar.DATE, day);
            return date.getTime();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 日期时分秒处理为00:00:00
     * @param date
     * @return
     */
    public static Date coverDate(Date date) {
        try {
            if (date == null){
                return null;
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(sdf.format(date));
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
        try {



//            Date date = DateUtil.str2Date("20191216");
//            if(null!=date) {
//                System.out.println("----" + date.getTime());
//            }
            DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(calDayInterval(new Date(),dateFormat2.parse("2022-12-13 00:31:01")));
            System.out.println("DateUtil.getDatePoor(new Date(),dateFormat2.parse(\"2020-12-31 00:31:01\"),0) = " + DateUtil.getDatePoor(new Date(), dateFormat2.parse("2022-11-16 00:31:01"), 0));
//            Date myDate2 = dateFormat2.parse("2020-12-31 00:31:01");
////            System.out.println(isEffectiveDate(myDate2, "23:00", "00:30"));
////            System.out.println(convert2String(new Date(), FORMAT));
//
//            DateFormat dateFormat3 = new SimpleDateFormat("yyyy-MM-dd");
//            Date myDate3 = dateFormat3.parse("2019-08-29");
////            System.out.println(compareToDate(new Date(), dateFormat2.parse("2019-08-14 10:34:00"),Calendar.MINUTE));
//
//            System.out.println(getDatePoor(new Date(), dateFormat2.parse("2019-08-14 10:34:00"),2));
//            System.out.println(getMonth(myDate2, myDate3));

//            System.out.println(DateUtils.parseDate("2019-09-03", PARSE_PATTERNS));
//            System.out.println(DateUtils.truncatedCompareTo(myDate2, myDate3, Calendar.DATE));
//            System.out.println(getMonth(myDate2, myDate3));
//            System.out.println(DateUtils.addMonths(myDate2, 2));
//            System.out.println(convert2String(myDate2, "yyyy-MM-dd"));
//
//            System.out.println(isCommonOrLeapYear(dateFormat3.parse("2020-02-30")));
//            System.out.println(convert2String(myDate2, "MM"));
//            System.out.println(DateUtils.addDays(myDate3, -1));
//            Date repayLastDay=DateUtils.addMonths(myDate3, 6);
//            if(!DateUtil.isCommonOrLeapYear(repayLastDay)//闰年
//	    			&&
//	    			DateUtil.convert2String(repayLastDay, "MM").equals("02")//2月
//	    			&&
//	    			(DateUtil.convert2String(myDate3, "dd").equals("30")||DateUtil.convert2String(myDate3, "dd").equals("31"))
//	    			) {
//	    		repayLastDay=DateUtils.addDays(repayLastDay, -1);
//	    	}
//            System.out.println("================");
//            System.out.println(repayLastDay);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算两个日期之间相差的月数
     * @param date1
     * @param date2
     * @return
     * @throws ParseException
     */
    public static int getMonthSpace(String date1, String date2)
             {

        int result = 0;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(Y_M_D_SPACE_FORMAT);

	        Calendar c1 = Calendar.getInstance();
	        Calendar c2 = Calendar.getInstance();

	        c1.setTime(sdf.parse(date1));
	        c2.setTime(sdf.parse(date2));

	        result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
		} catch (Exception e) {
			return -1;
		}
        return result == 0 ? 1 : Math.abs(result);
    }

    /**
     * 比较两个日期之间的大小
     * @param date1
     * @param date2
     * @param unit 秒-分-时-天-周-月-年 Calendar.DATE ....
     * @return
     */
    public static int compareToDate(Date date1,Date date2,int unit) {
    	Date dtmTime1 = DateUtils.truncate(date1, unit);
    	Date dtmTime2 = DateUtils.truncate(date2, unit);
    	return dtmTime1.compareTo(dtmTime2);
    }

    public static Date str2Date(String date) {
    	try {
    	    if(null==date){
    	        return null;
            }
    		return DateUtils.parseDate(date, PARSE_PATTERNS);
		} catch (Exception e) {
			GMFLOGGER.error("DateUtil str2Date转换日期error:{}",e);
			return null;
		}
    }
    /**
     * 获取两个日期相差几个月
     * @param start
     * @param end
     * @return
     */
    public static int getMonth(Date start, Date end) {
        if (start.after(end)) {
            Date t = start;
            start = end;
            end = t;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);
        int year = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
        if ((startCalendar.get(Calendar.DATE) == 1)&& (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1) && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1) && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
    }
    /**
     * 判断平年还是闰年
     * @param date
     * @return
     */
    public static boolean isCommonOrLeapYear(Date date) {
    	int dateInt = Integer.parseInt(convert2String(date, FORMAT_YERAR));
		if(dateInt % 4 != 0 || dateInt % 100 == 0 && dateInt % 400 != 0) {
		    GMFLOGGER.info("日期"+date+"是平年");
		    return true;
		}else {
			GMFLOGGER.info("日期"+date+"是闰年");
		    return false;
		}
	}

    /**
	 * 获取最后还款日
	 * @param totalStage 期数
	 * @param date CMC或者LMC系统时间
	 * @return
	 */
	public static Date installRepayLastDay(Integer totalStage,Date date) {
		//Date newDate=new Date();//系统当前日期
    	Date repayLastDay=DateUtils.addMonths(date, totalStage);//还款计划最后一日
    	//如果是闰年2月29天且申请日期为30日或者31日 则直接取值28号
    	if(!DateUtil.isCommonOrLeapYear(repayLastDay)//闰年
    			&&
    			DateUtil.convert2String(repayLastDay, "MM").equals("02")//2月
    			&&
    			(DateUtil.convert2String(date, "dd").equals("30")||DateUtil.convert2String(date, "dd").equals("31"))//风控通过日期是否是30或者31
    			) {
    		repayLastDay=DateUtils.addDays(repayLastDay, -1);
    	}
    	return repayLastDay;
	}

    /**
     * 计算两个日期的差值
     *
     * @param endDate   结束日期
     * @param startDate 开始日期
     * @param flag      差值类型 0-天 1-小时 2-分钟 3-秒，默认为秒
     * @return
     */
    public static long getDatePoor(Date endDate, Date startDate, int flag) {

        long nd = 1000 * 24 * 60 * 60;

        long nh = 1000 * 60 * 60;

        long nm = 1000 * 60;

        long ns = 1000;

        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startDate.getTime();
        if (flag == 0) {
            // 计算差多少天
            long day = diff / nd;
            return day;
        } else if (flag == 1) {
            // 计算差多少小时
            long hour = diff / nh;
            return hour;
        } else if (flag == 2) {
            // 计算差多少分钟
            long min = diff / nm;
            return min;
        } else if (flag == 3) {
            // 计算差多少秒//输出结果
            long sec = diff / ns;
            return sec;
        } else {
            // 计算差多少秒//输出结果
            long sec = diff / ns;
            return sec;
        }
    }

    /**
     * 计算两个日期之间的天数，支持跨年
     */
    public static long calDayInterval(Date startDate, Date endDate){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        LocalDate startLocalDate = LocalDate.parse(sdf.format(startDate));
        LocalDate endLocalDate = LocalDate.parse(sdf.format(endDate));
        return  startLocalDate.until(endLocalDate, ChronoUnit.DAYS);
    }

    /**
     * 格式化makeLoanTime date类型: yyyy-MM-dd 00:00:00
     */
    public static Date getMakeLoanTimeToLMC(String makeLoanTime){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = DateUtil.str2Date(makeLoanTime);
        String format = sdf.format(date);
        return DateUtil.str2Date(format);
    }

    /**
     * 格式化makeLoanTime: yyyyMMdd为yyyy-MM-dd
     */
    public static String getMakeLoanTime(String makeLoanTime){
        if (StringUtils.isEmpty(makeLoanTime)){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = DateUtil.str2Date(makeLoanTime);
        return sdf.format(date);
    }

    /**
     * 判断两个日期是否为同一天
     */
    public static boolean isSameDay(Date date1, Date date2){
        if(date1 != null && date2 != null) {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }

    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if(cal1 != null && cal2 != null) {
            return cal1.get(0) == cal2.get(0) && cal1.get(1) == cal2.get(1) && cal1.get(6) == cal2.get(6);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }

    public static Date getDateBefore(Date date, int day) {
        Date endTime = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, day);
            endTime = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return endTime;
    }

    /**
     * 获取差值后的时间
     * @param date
     * @param diff 差值
     * @param calendarField 差值区间如Calendar.MINUTE， Calendar.DAY_OF_MONTH等
     * @return
     */
    public static Date getDateTime(Date date, int diff, int calendarField) {
        Date endTime = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(calendarField, diff);
            endTime = calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return endTime;
    }

    public static Date getStartOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        return calendar.getTime();
    }

    public static Date getEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);

        return calendar.getTime();
    }


}
